/*!
 * \file queue.h
 * \brief Definition for the queue class.
 * \author Vijay Ramesh
 *
 * This is a simple queue class.
 */

#ifndef _QUEUE_H_
#define _QUEUE_H_
#define TRUE 1
#define FALSE 0

#include <stdbool.h>
#include <unistd.h>

struct queue_t;
struct qnode_t;

typedef struct qnode_t qnode_t;
typedef struct queue_t queue_t;

/*!
 * \brief A queue node struct.
 *
 * This is a simple queue node class with 2 pointers, next,value.
 * next points to the next node in the queue. value is a void pointer to the
 * address of the object being held in the queuenode.
 */
struct qnode_t
{
   qnode_t *next; /*!< next points to the next node in the queue. NULL if at the
                       end of the queue.*/
   void *value;   /*!< value points to the structure held by the queue node.
                       NULL if empty.*/
};

/*!
 * \brief A queue struct.
 *
 * This is a simple queue struct with 2 pointers, front, back and two
 * helper variables, empty, and size. front points to the front of the queue.
 * back points to the back of the queue. empty is a bool, that is set to false
 * when the queue is not empty and true when the queue is empty. size is the
 * size of the queue.
 */
struct queue_t
{
   qnode_t *front; /*!< front points to the qnode_t at the front of the queue.
                        NULL is the queue is empty.*/
   qnode_t *back;  /*!< back poinsts to the qnode_t at the back of the queue.
                        NULL if queue is empty.*/
   bool empty;     /*!< empty is a boolean that is set to TRUE if the queue
                        contains no nodes, and is FALSE if the queue contains
                        nodes.*/
   int size;       /*!< size is always set to the size of the queue. 0 when
                        queue is empty.*/
};

/*!
 * \brief The initializer for the queue object.
 *
 * This sets all the pointers in the queue object to NULL, size to 0, and empty
 * to true.
 *
 * \param queue is the queue_t pointer.
 */
void q_init ( queue_t *queue );

/*!
 * \brief An enqueue function
 *
 * This pushes a value to the back of the queue.
 *
 * \param queue is the queue_t pointer.
 * \param value is a pointer to the value to be pushed.
 * \return Returns an int, 0 on success and 1 on failure.
 */
int q_enqueue ( queue_t *queue, void *value );

/*!
 * \brief A dequeue function
 *
 * This pops the value at the front of the queue.
 *
 * \param queue is the queue_t pointer.
 * \param value is a pointer to the value to be pushed.
 * \return Returns A pointer to the value at the front of the queue.
 */
void * q_dequeue ( queue_t *queue );

/*!
 * \brief A destroy function
 *
 * This deletes all the space held by queue. The values held by each queuenode are
 * not deleted.
 *
 * \param queue is the queue_t pointer.
 */
void q_destroy ( queue_t *queue );

/*!
 * \brief A set empty function
 *
 * This sets the empty variable in the queue_t by determinig is the queue is
 * empty. This is mainly an internal function and never needs to be called upon,
 * although you can call it if you feel like it.
 *
 * \param queue is the queue_t pointer.
 */
void q_set_empty ( queue_t *queue );
#endif
